<!-- eslint-disable vue/no-mutating-props -->
<template>
  <el-form
    ref="formRef"
    :model="props.formData"
    :rules="props.formRules"
    v-bind="$attrs"
  >
    <el-row :gutter="20">
      <template v-for="(column, index) in props.formColumns" :key="index">
        <el-col
          v-if="isExpand || !column.hidden"
          :offset="column.offset"
          :span="column.span || formColumnsNum"
          :xs="12"
        >
          <el-form-item
            v-if="!column.hidden"
            :label="column.label"
            :label-position="labelPosition"
            :label-width="column.labelWidth"
            :prop="column.prop"
          >
            <!-- 表单标签提示词 -->
            <!-- <template #label>
              {{ column.label }}
              <el-tooltip
                class="box-item"
                content="Top Left prompts info"
                effect="dark"
                placement="top"
              >
                <el-icon color="orange"><Warning /></el-icon>
              </el-tooltip>
            </template> -->

            <slot v-if="$slots[`${column.prop}`]" :name="column.prop"></slot>
            <!-- 动态组件 -->
            <component
              :is="componentsTypes[column.xType]"
              v-else
              v-bind="column.componentProps"
              v-model="props.formData[column.prop]"
            >
              <!-- 如果是 Select 组件，渲染 ElOption -->
              <template v-if="column.xType === 'Select' && column.options">
                <component
                  :is="ElOption"
                  v-for="option in column.options"
                  :key="option.value"
                  :label="option.label"
                  :value="option.value"
                />
              </template>
              <!-- 如果是 CheckboxGroup 组件，渲染 ElCheckbox -->
              <template
                v-if="
                  column.xType === 'CheckboxGroup' &&
                  column.componentProps?.options
                "
              >
                <ElCheckbox
                  v-for="option in column.componentProps?.options"
                  :key="option.value"
                  :label="option.value"
                  :value="option.value"
                  @change="column.componentProps?.onChange"
                >
                  {{ option.label }}
                </ElCheckbox>
              </template>
              <!-- 如果是 el-radio-group组件，渲染el-radio-button -->
              <template
                v-if="
                  column.xType === 'RadioGroup' &&
                  column.componentProps?.options
                "
              >
                <ElRadioButton
                  v-for="option in column.componentProps.options"
                  :key="option.value"
                  :label="option.value"
                  :value="option.value"
                >
                  {{ option.label }}
                </ElRadioButton>
              </template>
            </component>
          </el-form-item>
        </el-col>
      </template>
      <!-- 展开筛选 -->
      <el-col v-if="formExpand" :span="8" :xs="24">
        <el-form-item>
          <el-button type="primary" @click="Search">
            {{ $t('common.form.query') }}
          </el-button>
          <el-button @click="formRef?.resetFields()">
            {{ $t('common.form.reset') }}
          </el-button>
          <el-button
            v-if="formColumns.length > 2"
            type="text"
            @click="expandHandle"
          >
            {{ $t('common.form.expand') }}
            <el-icon v-if="!isExpand"><ArrowDown /></el-icon>
            <el-icon v-else><ArrowUp /></el-icon>
          </el-button>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>
<script lang="ts" setup name="kun-form">
import type { FormInstance } from 'element-plus';

import type { formColumnsType, labelPositionType } from './type';

import { markRaw, type PropType, ref, watch } from 'vue';

import { $t } from '@vben/locales';

import { ArrowDown, ArrowUp } from '@element-plus/icons-vue';
import {
  ElAutocomplete,
  ElCascader,
  ElCheckbox,
  ElCheckboxGroup,
  ElColorPicker,
  ElDatePicker,
  ElInput,
  ElInputNumber,
  ElOption,
  ElRadio,
  ElRadioButton,
  ElRadioGroup,
  ElRate,
  ElSelect,
  ElSlider,
  ElSwitch,
  ElTimePicker,
  ElTimeSelect,
  ElTransfer,
  ElTree,
  ElTreeSelect,
} from 'element-plus';

const props = defineProps({
  // 表单数据
  formData: {
    type: Object,
    default: () => ({}),
  },
  // 表列默认宽度
  formColumnsNum: {
    type: Number,
    default: 12,
    required: true,
  },
  formColumns: {
    type: Array as PropType<formColumnsType[]>,
    default: () => [],
  },
  // 表单label位置
  labelPosition: {
    type: String as PropType<labelPositionType>,
    default: 'right',
  },
  // 表单规则验证
  formRules: {
    type: Object,
    default: () => ({}),
  },
  // 是否开启表单伸缩
  formExpand: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(['SearchHandle']); // 声明emit
// 是否展开
const isExpand = ref(false);
// 定义动态组件
const componentsTypes: Record<string, any> = markRaw({
  Input: ElInput,
  Autocomplete: ElAutocomplete,
  Select: ElSelect,
  Option: ElOption,
  DatePicker: ElDatePicker,
  TimePicker: ElTimePicker,
  TimeSelect: ElTimeSelect,
  InputNumber: ElInputNumber,
  Radio: ElRadio,
  Checkbox: ElCheckbox,
  Switch: ElSwitch,
  Slider: ElSlider,
  Rate: ElRate,
  Transfer: ElTransfer,
  CheckboxGroup: ElCheckboxGroup,
  Cascader: ElCascader,
  RadioGroup: ElRadioGroup,
  ColorPicker: ElColorPicker,
  Tree: ElTree,
  TreeSelect: ElTreeSelect,
});

// 收缩展开
const expandHandle = async () => {
  isExpand.value = !isExpand.value;
  props.formColumns.forEach((item: any, index: any) => {
    if (index < 2) return;
    item.hidden = !isExpand.value;
  });
};
// 搜索
const Search = () => {
  // eslint-disable-next-line vue/custom-event-name-casing
  emit('SearchHandle');
};
// 监听表单配置项变化
watch(
  () => props.formColumns,
  (newVal) => {
    if (!props.formExpand) return; // 如果没有开启表单伸缩，则不需要处理
    if (newVal.length > 2) {
      // 如果表单配置项长度大于2，则默认展开
      props.formColumns.forEach((item: any, index: any) => {
        // 如果表单配置项的索引小于2，则不需要隐藏
        if (index < 2) return;
        // 如果表单配置项的索引大于2，则需要隐藏
        item.hidden = !isExpand.value;
      });
    }
  },
  { deep: true, immediate: true },
);

// 将表单绑定的ref暴露给父组件
const formRef = ref<FormInstance>();
defineExpose({ formRef });
</script>
